#include "FbxAnimationChannel.h"

namespace GC
{
	GC::FbxAnimationChannel::FbxAnimationChannel( FbxAnimLayer* a_layer, FbxNode* a_node ,const ChannelType a_type, const double a_deltaFrameTime)		
	{
		m_x = std::make_shared<GC::FbxAnimationCurve>( TryToGetCurve( a_layer, a_node, a_type, FBXSDK_CURVENODE_COMPONENT_X), a_deltaFrameTime);
		m_y = std::make_shared<GC::FbxAnimationCurve>(TryToGetCurve(a_layer, a_node, a_type, FBXSDK_CURVENODE_COMPONENT_Y), a_deltaFrameTime);
		m_z = std::make_shared<GC::FbxAnimationCurve>(TryToGetCurve(a_layer, a_node, a_type, FBXSDK_CURVENODE_COMPONENT_Z), a_deltaFrameTime);
	}	
	
	/// <summary>
	/// Determines whether this instance is valid by checking the curve channels
	/// </summary>
	/// <returns></returns>
	const bool FbxAnimationChannel::IsValid() const
	{
		return (m_x->IsValid() || m_y->IsValid() || m_z->IsValid());
	}

	const int GC::FbxAnimationChannel::GetAnimationLength() const
	{
		int f_length = m_x->GetAnimationLength();

		int f_tempLength = m_y->GetAnimationLength();

		if (f_tempLength > f_length) f_length = f_tempLength;

		f_tempLength = m_z->GetAnimationLength();

		if (f_tempLength > f_length) f_length = f_tempLength;

		return f_length;		
	}

	const bool GC::FbxAnimationChannel::HasValueAtFrame( const int a_frameNumber ) const
	{
		return m_x->HasValueAtFrame( a_frameNumber) || m_y->HasValueAtFrame( a_frameNumber) || m_z->HasValueAtFrame( a_frameNumber );
	}

	/// <summary>
	/// Gets the value at a certain frame by writing the data to a_dest
	/// </summary>
	/// <param name="a_frame">The frame number.</param>
	/// <param name="a_dest">The destination vector.</param>
	void GC::FbxAnimationChannel::GetValueAtFrame(const int a_frame, FbxVector4& a_dest) const
	{
		if (m_x->HasValueAtFrame(a_frame) )
		{
			a_dest[0] = m_x->GetValueAtFrame( a_frame);
		}
		if (m_y->HasValueAtFrame( a_frame ) )
		{
			a_dest[1] = m_y->GetValueAtFrame(a_frame);
		}
		if (m_z->HasValueAtFrame(a_frame ) )
		{
			a_dest[2] = m_z->GetValueAtFrame( a_frame );
		}
	}

	FbxAnimCurve* GC::FbxAnimationChannel::TryToGetCurve(FbxAnimLayer* a_layer, FbxNode* a_node, const ChannelType a_type, const char* a_dimension)
	{
		FbxAnimCurve* f_animCurve = nullptr;

		switch ( a_type )
		{
			case ChannelType::Translation: 
				f_animCurve = a_node->LclTranslation.GetCurve( a_layer, a_dimension);
				break;
			case ChannelType::Rotation: 
				f_animCurve = a_node->LclRotation.GetCurve( a_layer, a_dimension );
				break;
			case ChannelType::Scale: 
				f_animCurve = a_node->LclScaling.GetCurve( a_layer, a_dimension );
				break;			
		}

		return f_animCurve;		
	}
}